package com.daka.tools.wechatPay;

import com.daka.exception.ServiceRuntimeException;
import com.daka.tools.ConfigUtil;
import com.daka.tools.http.HttpsUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashMap;

/**
 * @author jayli
 */
public class WechatUtil {

    protected static Logger LOGGER = LoggerFactory.getLogger(WechatUtil.class);

    // First step of getting openId. Get code
    public static String getWXOauthPageApi(String appId, String url, String scope) {
        if (StringUtils.isEmpty(scope)) {
            scope = "snsapi_base";   //snsapi_userinfo 进入授权页面 ，可以获取用户信息   snsapi_base静默授权 只能拿到openId
        }
        return "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + url
                + "&response_type=code&scope=" + scope + "&state=STATE#wechat_redirect";
    }

    public static String getWXOauthPageApi(String appId, String url) {
        return getWXOauthPageApi(appId, url, null);
    }

    // Second step of getting openId. Get access_token with code returned in
    // step one
    private static String getWXOauthAccessTokenApi(String appId, String secret, String code) {
        return "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret + "&code="
                + code + "&grant_type=authorization_code";
    }

    private static String getWXUserInfoBySNSApi(String openid, String token) {
        return "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid + "&lang=zh_CN";
    }

    public static HashMap<String, String> getOpenId(String appId, String secret, String code) {
        String url = getWXOauthAccessTokenApi(appId, secret, code);
        JSONObject json = new JSONObject();
        try {
            json = HttpsUtil.readJsonFromUrl(url);

            if (json.has("openid")) {
                HashMap<String, String> hashMap = new HashMap<>();
                hashMap.put("openid", json.getString("openid"));
                hashMap.put("token", json.getString("access_token"));
                return hashMap;
            } else {
                return null;
            }
        } catch (JSONException e) {
            throw new ServiceRuntimeException("Message returned from wechat is not valid json: " + json);
        } catch (IOException e) {
            throw new ServiceRuntimeException("Can not open url: " + url);
        }
    }

    public static String getAccessToken(String appId, String secret, String code) {
        String url = getWXOauthAccessTokenApi(appId, secret, code);
        JSONObject json = new JSONObject();
        try {
            json = HttpsUtil.readJsonFromUrl(url);

            if (json.has("access_token")) {
                return json.getString("access_token");
            } else {
                return "";
            }
        } catch (JSONException e) {
            throw new ServiceRuntimeException("Message returned from wechat is not valid json: " + json);
        } catch (IOException e) {
            throw new ServiceRuntimeException("Can not open url: " + url);
        }

    }

    public static JSONObject getUserBySNS(String openid, String token) {
        String url = getWXUserInfoBySNSApi(openid, token);

        JSONObject json = new JSONObject();
        try {
            json = HttpsUtil.readJsonFromUrl(url);

            return json;

        } catch (JSONException e) {
            throw new ServiceRuntimeException("Message returned from wechat is not valid json: " + json);
        } catch (IOException e) {
            throw new ServiceRuntimeException("Can not open url: " + url);
        }

    }

    public static Token token(String appid, String secret) {
        HttpUriRequest httpUriRequest = RequestBuilder.get().setUri(ConfigUtil.getBaseUrl() + "/cgi-bin/token")
                .addParameter("grant_type", "client_credential").addParameter("appid", appid)
                .addParameter("secret", secret).build();
        return LocalHttpClient.executeJsonResult(httpUriRequest, Token.class);
    }

    public static Ticket ticketGetticket(String access_token) {
        HttpUriRequest httpUriRequest = RequestBuilder.post()
                .setUri(ConfigUtil.getBaseUrl() + "/cgi-bin/ticket/getticket")
                .addParameter("access_token", access_token).addParameter("type", "jsapi").build();
        return LocalHttpClient.executeJsonResult(httpUriRequest, Ticket.class);
    }

    public static UserInfo getUserInfo(String token, String openid) {
        HttpUriRequest httpUriRequest = RequestBuilder.get().setUri(ConfigUtil.getBaseUrl() + "/cgi-bin/user/info")
                .addParameter("access_token", token).addParameter("openid", openid).addParameter("lang", "zh_CN")
                .build();
        return LocalHttpClient.executeJsonResult(httpUriRequest, UserInfo.class);
    }
}